/*
 * @Description:
 * @Version: 5.0
 * @Autor: Lujiantu
 * @Date: 2020-12-28 09:06:26
 * @LastEditTime: 2025-01-28 13:40:25
 */

#include "./Common_Include.h"
Ram s_dev_key_t gDev_Key;

#define Dev_Key_Put(cmd, val) (gDev_Key.Type.Cmd = cmd, gDev_Key.Type.Val = val)

void Dev_Key_Init(void)
{
	memset(&gDev_Key, 0, sizeof(gDev_Key));
}

s_dev_key_cv_t *Dev_Key_Get(unsigned char clr)
{
	static Ram s_dev_key_cv_t p = {0, 0};
	memcpy(&p, &gDev_Key.Type, sizeof(p));
	if (clr == REF_KEY_CLR)
	{
		Dev_Key_Put(e_KEY_NO, 0);
	}
	return &p;
}

void Dev_Key_DownTime(void)
{
	unsigned char keydown_cnt = 0, i;
	unsigned long key;
	gDev_Key.Down_Time++;
	if ((gDev_Key.New_Sta == 0) || (gDev_Key.Old_Sta < gDev_Key.New_Sta))
	{
		gDev_Key.Down_Time = 0;
	}
	gDev_Key.Old_Sta = gDev_Key.New_Sta;

	//========================================
	key = gDev_Key.Old_Sta;
	for (i = 0; i < 32; i++)
	{
		if (key & (1 << i))
		{
			keydown_cnt++;
		}
	}
	if (keydown_cnt > 1)
	{
		gDev_Key.EnShortUp = REF_KEY_UP_DISENABLE;
	}
	if (gDev_Key.Old_Sta == 0)
	{
		gDev_Key.EnShortUp = REF_KEY_UP_ENABLE;
	}
}
void Dev_Key_Type_DownUp(void)
{
	Ram unsigned char i;
	CONST unsigned short time[3] = {KEY_DOWN_SHORT_TIME_CNT, KEY_DOWN_LONG0_TIME_CNT, KEY_DOWN_LONG1_TIME_CNT};
	// CONST signed char *time_str[3] = {"KEY_DOWN_SHORT:", "KEY_DOWN_LONG0:", "KEY_DOWN_LONG1:"};

	// 按下时的建值保存
	for (i = 0; i < ARR_CNT(time); i++)
	{
		if (gDev_Key.Down_Time == time[i])
		{
			Dev_Key_Put(e_KEY_DOWN + i, gDev_Key.New_Sta);
			// Dev_IoPrint_Str_DecStr(time_str[i], gDev_Key.Old_Sta);
		}
	}
	// 按键抬起时的建值保存
	if (gDev_Key.Old_Sta > gDev_Key.New_Sta)
	{
		if ((time[0] <= gDev_Key.Down_Time) && (gDev_Key.Down_Time < time[1])) // 短按抬起要在长按时间以内
		{
			if (gDev_Key.EnShortUp == REF_KEY_UP_ENABLE)
			{
				Dev_Key_Put(e_KEY_UP, gDev_Key.Old_Sta ^ gDev_Key.New_Sta); // 保存按键上降沿

				// Dev_IoPrint_Str_DecStr("\ne_KEY_UP  = ", gDev_Key.Old_Sta);
			}
		}
	}
}
#ifdef KEY_DOWN_LONGX_TIME_CNT
void Dev_Key_Longx(void)
{
#ifdef KEY_DOWN_LONGX_SPEED_CNT
	gDev_Key.Downx_Time++;
	if (gDev_Key.Downx_Time > KEY_DOWN_LONGX_TIME_CNT)
	{
		gDev_Key.Downx_Time = KEY_DOWN_LONGX_TIME_CNT - KEY_DOWN_LONGX_SPEED_CNT;
		Dev_Key_Put(e_KEY_CHANGX_DOWN, gDev_Key.New_Sta);
		// Dev_IoPrint_Str_DecStr("\ne_KEY_CHANGX_DOWN  = ", gDev_Key.New_Sta);
	}
	if ((gDev_Key.New_Sta == 0) || (gDev_Key.Old_Sta < gDev_Key.New_Sta))
	{
		gDev_Key.Downx_Time = 0;
	}
#endif
#ifdef KEY_DOWN_LONGX_SPEED_CHANGE
	static Ram unsigned char cnt = 0;
	CONST unsigned short change_time_tab[] = {500l / DEV_KEY_TASK_TIME, 500l / DEV_KEY_TASK_TIME, 500l / DEV_KEY_TASK_TIME, 500l / DEV_KEY_TASK_TIME,
											  250l / DEV_KEY_TASK_TIME, 250l / DEV_KEY_TASK_TIME, 250l / DEV_KEY_TASK_TIME, 250l / DEV_KEY_TASK_TIME,
											  250l / DEV_KEY_TASK_TIME, 250l / DEV_KEY_TASK_TIME, 250l / DEV_KEY_TASK_TIME, 250l / DEV_KEY_TASK_TIME,
											  125l / DEV_KEY_TASK_TIME};
	gDev_Key.Downx_Time++;
	if (gDev_Key.Downx_Time > KEY_DOWN_LONGX_TIME_CNT)
	{
		gDev_Key.Downx_Time = KEY_DOWN_LONGX_TIME_CNT - change_time_tab[cnt];
		LIMIT_ADD_STEP(cnt, (ARR_CNT(change_time_tab) - 1), 1l);
		Dev_Key_Put(e_KEY_CHANGX_DOWN, gDev_Key.New_Sta);
		// Dev_IoPrint_Str_DecStr("\ne_KEY_CHANGX_DOWN  = ", gDev_Key.New_Sta);
	}
	if ((gDev_Key.New_Sta == 0) || (gDev_Key.Old_Sta < gDev_Key.New_Sta))
	{
		cnt = 0;
		gDev_Key.Downx_Time = 0;
	}
#endif
}
#endif
void Dev_Key_Scan(void)
{
	static Ram unsigned char tick = 0;
	if (Drv_Autoload_Ntick_u8(&tick, DEV_KEY_TASK_TIME)) /* 需要最小时间不要小于5ms，因为有print */
	{
		Dev_Key_Type_NewSta(); /* 按键类型:按键状态 */
		Dev_Key_Type_DownUp(); /* 按键类型:按键按下抬起 */
		Dev_Key_DownTime();	   /* 按键类型:按键时间 */
#ifdef KEY_DOWN_LONGX_TIME_CNT
		Dev_Key_Longx();
#endif
	}
}
